/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package spaceinvaders;

import Util.Timer;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javazoom.jl.decoder.JavaLayerException;

/**
 *
 * @author Lucas
 */
public class Jogo extends JFrame {
    //Parte funcional do jogo

    Func fu;
    //int frames = 0;
    //Limite de frames por segundo
    final int fps = 30;
    //Timer para controle dos frames por segundo
    Timer fpsCtrl;
    //Configurações para carregar/salvar os recordes
    File file;
    String[] recordes;
    int[] pontos;

    public Jogo() throws JavaLayerException, URISyntaxException, IOException {
        //Configurações de JFrame
        Toolkit tk = getToolkit();
        fu = new Func();
        //Adiciona a parte gráfica do jogo, que está associada à funcional
        add(fu.getGraf());
        
        setTitle("Space Invaders");
        URL icone = Jogo.class.getResource("/Imagens/icone.png");
        setIconImage(new ImageIcon(icone).getImage());
        fpsCtrl = new Timer();
        setVisible(true);
        setResizable(false);

        //Pega os tamanhos de bordas das janelas para posicionar corretamente os elementos do jogo
        Insets i = this.getInsets();
        setSize(i.left + 638, i.top + 478);

        //Coloca a janela no centro da tela
        setLocation((tk.getScreenSize().width - this.getSize().width) / 2, (tk.getScreenSize().height - this.getSize().height) / 2);

        //Arquivo de recordes
        file = new File("Recordes.lol");
        recordes = new String[10];
        pontos = new int[10];

        //Tenta ler o arquivo com os recordes do jogo
        try {
            FileReader reader = new FileReader(file);
            BufferedReader br = new BufferedReader(reader);
            String linha = null;
            StringTokenizer st;

            int j = 0;
            while ((linha = br.readLine()) != null) {
                st = new StringTokenizer(linha, " ");
                recordes[j] = st.nextToken();
                pontos[j] = Integer.parseInt(st.nextToken());
                j++;
            }
            reader.close();
            br.close();
        //Se o arquivo não existir, cria recordes vazios
        } catch (FileNotFoundException ex) {
            for (int j = 0; j < 10; j++) {
                recordes[j] = "Ninguém";
                pontos[j] = 0;
            }
        } finally {
            fu.getGraf().setRecordes(recordes, pontos);
        }

        //Quando o usuário fechar a janela, escreve os recordes no arquivo e encerra o jogo
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                int[] pontos = fu.getGraf().getPontos();
                String[] recordes = fu.getGraf().getRecordes();
                try {
                    FileWriter writer = new FileWriter(file);
                    BufferedWriter bw = new BufferedWriter(writer);
                    for (int i = 0; i < 10; i++) {
                        bw.write(recordes[i] + ' ' + pontos[i] + '\n');
                    }
                    bw.close();
                    writer.close();
                } catch (IOException ex) {
                    Logger.getLogger(Jogo.class.getName()).log(Level.SEVERE, null, ex);
                }

                System.exit(0);
            }
        });
    }

    //Loop principal do jogo
    public void loop() throws InterruptedException, JavaLayerException {
        long tempo;
        
        while (true) {
            tempo = System.nanoTime();
            //Reinicia o controle de frames por segundo
            fpsCtrl.inicia();
            //Atualiza a parte funcional
            fu.update();
            System.out.println(System.nanoTime() - tempo);
            //Atrasa o jogo para manter um limite de fps
            atraso();
        }
    }

    public void atraso() throws InterruptedException {
        /*Para manter um controle de fps, é preciso fazer o jogo
         * esperar caso não tenha passado o tempo mínimo.
         * Então, faz-se essa verificação e, caso ainda não tenha
         * passado esse tempo, faz-se o jogo esperar o tempo restante.*/
        if (fpsCtrl.tempo() < 1000 / fps) {
            Thread.sleep((1000 / fps) - fpsCtrl.tempo());
        }
        //Atualiza a mensagem de fps na parte gráfica
        fu.getGraf().setFPS(1000 / fpsCtrl.tempo());
    }
}
